home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / Apps / Astro / ephem / Source / listing.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  7.4 KB  |  318 lines

  1. /* code to support the listing capabilities.
  2.  * idea is to let the operator name a listing file and mark some fields for
  3.  * logging. then after each screen update, the logged fields are written to
  4.  * the listing file in the same manner as they appeared on the screen.
  5.  * 
  6.  * format of the listing file is one line per screen update.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <math.h>
  11. #include "screen.h"
  12.  
  13. extern char *strcpy();
  14.  
  15. #ifdef VMS
  16. #include <perror.h>
  17. #include <errno.h>
  18. #else
  19. extern char *sys_errlist[];
  20. extern errno;
  21. #endif
  22.  
  23. #define    errsys    (sys_errlist[errno])
  24.  
  25.  
  26. #define    TRACE(x)    {FILE *fp = fopen("trace","a"); fprintf x; fclose(fp);}
  27.  
  28. #define    MAXLSTFLDS    10    /* max number of fields we can track.
  29.                  * note we can't store more than NFLOGS fields
  30.                  * anyway (see flog.c).
  31.                  */
  32. #define    FNLEN        (14+1)    /* longest filename; plus 1 for \0 */
  33.  
  34. static char lst_filename[FNLEN] = "ephem.lst";    /* default plot file name */
  35. static FILE *lst_fp;        /* the plot file; == 0 means don't plot */
  36.  
  37. /* store rcfpack()s for each field to track, in l-to-r order */
  38. static int lstflds[MAXLSTFLDS];
  39. static int nlstflds;        /* number of lstflds[] in actual use */
  40.  
  41. static int lstsrchfld;        /* set when the Search field is to be listed */
  42.  
  43. /* picked the Listing label:
  44.  * if on, just turn it off.
  45.  * if off, turn on, define fields or select name of file to list to and do it.
  46.  * TODO: more flexibility, more relevance.
  47.  */
  48. listing_setup()
  49. {
  50.     if (lst_fp)
  51.         lst_turn_off();
  52.     else {
  53.         static char *chcs[] = {
  54.         "Select fields", "Display a listing file", "Begin listing"
  55.         };
  56.         static int fn;    /* start with 0, then remember for next time */
  57.     ask:
  58.         switch (popup(chcs, fn, nlstflds > 0 ? 3 : 2)) {
  59.         case 0: fn = 0; lst_select_fields(); goto ask;
  60.         case 1: fn = 1; lst_file(); goto ask;
  61.         case 2: fn = 2; lst_turn_on(); break;
  62.         default: break;
  63.         }
  64.     }
  65. }
  66.  
  67. /* write the active listing to the current listing file, if one is open. */
  68. listing()
  69. {
  70.     if (lst_fp) {
  71.         int n;
  72.         double flx;
  73.         char flstr[32];
  74.         if (!srch_ison() && lstsrchfld) {
  75.         /* if searching is not on but we are listing the search
  76.          * funtion we must evaluate and log it ourselves here and now.
  77.          * lst_turn_on() insured there is a good function to eval.
  78.          * N.B. if searching IS on, we rely on main() having called
  79.          * srch_eval() BEFORE plot() so it is already evaluated.
  80.          */
  81.         double e;
  82.         char errmsg[128];
  83.         if (execute_expr (&e, errmsg) < 0) {
  84.             f_msg (errmsg);
  85.             lst_turn_off();
  86.             return;
  87.         } else {
  88.             (void) sprintf (flstr, "%g", e);
  89.             (void) flog_log (R_SRCH, C_SRCH, e, flstr);
  90.         }
  91.         }
  92.  
  93.         /* list in order of original selection */
  94.         for (n = 0; n < nlstflds; n++)
  95.         if (flog_get (lstflds[n], &flx, flstr) == 0)
  96.             (void) fprintf (lst_fp, "%s  ", flstr);
  97.         (void) fprintf (lst_fp, "\n");
  98.     }
  99. }
  100.  
  101. listing_prstate (force)
  102. int force;
  103. {
  104.     static last;
  105.     int this = lst_fp != 0;
  106.  
  107.     if (force || this != last) {
  108.         f_string (R_LISTING, C_LISTINGV, this ? " on" : "off");
  109.         last = this;
  110.     }
  111. }
  112.  
  113. listing_ison()
  114. {
  115.     return (lst_fp != 0);
  116. }
  117.  
  118. static
  119. lst_reset()
  120. {
  121.     int *lp;
  122.  
  123.     for (lp = lstflds; lp < &lstflds[nlstflds]; lp++) {
  124.         (void) flog_delete (*lp);
  125.         *lp = 0;
  126.     }
  127.     nlstflds = 0;
  128.     lstsrchfld = 0;
  129. }
  130.  
  131. /* let operator select the fields he wants to have in his listing.
  132.  * register them with flog and keep rcfpack() in lstflds[] array.
  133.  * as a special case, set lstsrchfld if Search field is selected.
  134.  */
  135. static
  136. lst_select_fields()
  137. {
  138.     static char hlp[] = "move and RETURN to select a field, or q to quit";
  139.     static char sry[] = "Sorry; can not list any more fields.";
  140.     int f = rcfpack(R_UT,C_UTV,0); /* TODO: start where main was? */
  141.     int sf = rcfpack (R_SRCH,C_SRCH,0);
  142.     char buf[64];
  143.     int i;
  144.  
  145.     lst_reset();
  146.     for (i = 0; i < MAXLSTFLDS; i++) {
  147.         (void) sprintf(buf,"select field for column %d or q to quit", i+1);
  148.         f = sel_fld (f, alt_menumask()|F_PLT, buf, hlp);
  149.         if (!f)
  150.         break;
  151.         if (flog_add (f) < 0) {
  152.         f_msg (sry);
  153.         break;
  154.         }
  155.         lstflds[i] = f;
  156.         if (f == sf)
  157.         lstsrchfld = 1;
  158.     }
  159.     if (i == MAXLSTFLDS)
  160.         f_msg (sry);
  161.     nlstflds = i;
  162. }
  163.  
  164. static
  165. lst_turn_off ()
  166. {
  167.     (void) fclose (lst_fp);
  168.     lst_fp = 0;
  169.     listing_prstate(0);
  170. }
  171.  
  172. /* turn on listing facility.
  173.  * establish a file to use (and thereby set lst_fp, the "listing-is-on" flag).
  174.  * also check that there is a srch function if it is being used.
  175.  */
  176. static
  177. lst_turn_on ()
  178. {
  179.     int sf = rcfpack(R_SRCH, C_SRCH, 0);
  180.     char fn[FNLEN], fnq[NC];
  181.     char *optype;
  182.     int n;
  183.  
  184.     /* insure there is a valid srch function if we are to list it */
  185.     for (n = 0; n < nlstflds; n++)
  186.         if (lstflds[n] == sf && !prog_isgood()) {
  187.         f_msg ("Listing search function but it is not defined.");
  188.         return;
  189.         }
  190.  
  191.     /* prompt for file name, giving current as default */
  192.     (void) sprintf (fnq, "file to write <%s>: ", lst_filename);
  193.     f_prompt (fnq);
  194.     n = read_line (fn, sizeof(fn)-1);
  195.  
  196.     /* leave plotting off if type END.
  197.      * reuse same fn if just type \n
  198.      */
  199.     if (n < 0)
  200.         return;
  201.     if (n > 0)
  202.         (void) strcpy (lst_filename, fn);
  203.  
  204.     /* give option to append if file already exists */
  205.     optype = "w";
  206.     if (access (lst_filename, 2) == 0) {
  207.         while (1) {
  208.         f_prompt ("files exists; append or overwrite (a/o)?: ");
  209.         n = read_char();
  210.         if (n == 'a') {
  211.             optype = "a";
  212.             break;
  213.         }
  214.         if (n == 'o')
  215.             break;
  216.         }
  217.     }
  218.  
  219.     /* listing is on if file opens ok */
  220.     lst_fp = fopen (lst_filename, optype);
  221.     if (!lst_fp) {
  222.         (void) sprintf (fnq, "can not open %s: %s", lst_filename, errsys);
  223.         f_msg (fnq);
  224.     } else {
  225.         /* add a title if desired */
  226.         static char tp[] = "Title (q to skip): ";
  227.         f_prompt (tp);
  228.         if (read_line (fnq, PW - sizeof(tp)) > 0)
  229.         (void) fprintf (lst_fp, "%s\n", fnq);
  230.     }
  231.  
  232.     listing_prstate (0);
  233. }
  234.  
  235. /* ask operator for a listing file to show. if it's ok, do it.
  236.  */
  237. static
  238. lst_file ()
  239. {
  240.     char fn[FNLEN], fnq[64];
  241.     FILE *lfp;
  242.     int n;
  243.  
  244.     /* prompt for file name, giving current as default */
  245.     (void) sprintf (fnq, "file to read <%s>: ", lst_filename);
  246.     f_prompt (fnq);
  247.     n = read_line (fn, sizeof(fn)-1);
  248.  
  249.     /* forget it if type END.
  250.      * reuse same fn if just type \n
  251.      */
  252.     if (n < 0)
  253.         return;
  254.     if (n > 0)
  255.         (void) strcpy (lst_filename, fn);
  256.  
  257.     /* show it if file opens ok */
  258.     lfp = fopen (lst_filename, "r");
  259.     if (lfp) {
  260.         display_listing_file (lfp);
  261.         (void) fclose (lfp);
  262.     } else {
  263.         char buf[NC];
  264.         (void) sprintf (buf, "can not open %s: %s", lst_filename, errsys);
  265.         f_prompt (buf);
  266.         (void)read_char();
  267.     }
  268. }
  269.  
  270. /* display the given listing file on the screen.
  271.  * allow for files longer than the screen.
  272.  * N.B. do whatever you like but redraw the screen when done.
  273.  */
  274. static
  275. display_listing_file (lfp)
  276. FILE *lfp;
  277. {
  278.     static char eofp[] = "[End-of-file. Hit any key to resume...] ";
  279.     static char p[] =    "[Hit any key to continue or q to quit...] ";
  280.     char buf[NC+2];    /* screen width plus for '\n' and '\0' */
  281.     int nc, nl;
  282.  
  283.     c_erase();
  284.     nl = 0;
  285.     while (1) {
  286.         (void) fgets (buf, sizeof(buf), lfp);
  287.         if (feof(lfp)) {
  288.         printf (eofp);
  289.         (void) read_char();
  290.         break;
  291.         }
  292.         /* make sure last char is \n, even if it's a long line */
  293.         nc = strlen (buf);
  294.         if (nc == NC+1) {
  295.         (void) ungetc (buf[NC], lfp);
  296.         buf[NC] = '\n';
  297.         }
  298.         printf ("%s\r", buf);
  299.         if (++nl == NR-1) {
  300.         /* read-ahead one char to check for eof */
  301.         int rach = getc (lfp);
  302.         if (feof(lfp)) {
  303.             (void) printf (eofp);
  304.             (void) read_char();
  305.             break;
  306.         } else
  307.             (void) ungetc (rach, lfp);
  308.         (void) printf (p);
  309.         if (read_char() == END)
  310.             break;
  311.         c_erase();
  312.         nl = 0;
  313.         }
  314.     }
  315.  
  316.     redraw_screen (2);    /* full redraw */
  317. }
  318.